#include <stdlib.h>
#include "Arbre.h"
#include "Symbole.h"
#include "SymboleValue.h"
#include "Valeur.h"
#include <typeinfo>


////////////////////////////////////////////////////////////////////////////////
SymboleValue::SymboleValue(Symbole s, string type, unsigned int ligne) :
        Symbole(s.getChaine()) {
    if (s == "<ENTIER>") {
        valeur = new ValeurInt(atoi(s.getChaine().c_str()));
        // valeur = atoi(s.getChaine().c_str()); // c_str convertit une string en char*
        defini = true;
		this->type = "entier";
    }
    else if (s == "<REEL>") {
        /*float val;
        istringstream iss(s);
        iss >> val;
        //  valeur = atoi(s.getChaine().c_str()); // c_str convertit une string en char*
        valeur = new ValeurFloat(val);*/
        valeur = new ValeurFloat(atof(s.getChaine().c_str()));
        defini = true;
        this->type = "reel";
    }
    else if (s == "<CHAINE>") {
        valeur = new ValeurString(s.getChaine());
        // valeur = s.getChaine().c_str()); // c_str convertit une string en char*
        defini = true;
        this->type = "chaine";
    }
    else if (s == "<CARACT>") {
        valeur = new ValeurString(s.getChaine());
        //valeur = atoi(s.getChaine().c_str()); // c_str convertit une string en char*
        defini = true;
        this->type = "chara";
    }
    else {
        if (type=="entier") {
            valeur = new ValeurInt(0);
            this->type = type;
        }
        if (type=="reel") {
            valeur = new ValeurFloat(0.0);
			this->type = type;
		}
        if (type=="chaine") {
            valeur = new ValeurString("\0");
            this->type = "chaine";
        }
        if (type=="chara") {
            valeur = new ValeurString('\0');
            this->type = type;
        }
        defini = false;
    }
   this->ligne=ligne;
}

////////////////////////////////////////////////////////////////////////////////
//void SymboleValue::afficher(unsigned short indentation) {
//	Noeud::afficher(indentation);
//	cout << "Feuille - Symbole value : " << getChaine() << endl; // on affiche la chaine du symbole
//}

////////////////////////////////////////////////////////////////////////////////
// Attention : cette fonction (operator) n'est pas membre de la classe SymboleValue
ostream & operator <<(ostream & cout, SymboleValue symb) {
    cout << (Symbole) symb << "\t\t -, " << symb.getType() << " (ligne " << symb.getLigne() <<") Valeur=";
    Valeur* val = symb.valeur;
    if (symb.defini) {
       if (typeid(*val) == typeid(ValeurInt))
            cout << ((ValeurInt*)val)->getValeur() << " ";
       else if (typeid(*val) == typeid(ValeurFloat))
            cout << ((ValeurFloat*)val)->getValeur() << " ";
       else if (typeid(*val) == typeid(ValeurString))
            cout << ((ValeurString*)val)->getValeur() << " ";
    /*   else if (typeid(valeur) == typeid(ValeurChar*))
            cout << ((ValeurChar*)valeur)->getValeur() << " ";*/
    }
    else
        cout << "indefinie ";
    return cout;
}

Valeur*  SymboleValue::getValeur() {
    return this->valeur;                        // accesseur
}

void SymboleValue::setValeur(Valeur* valeur)    {
    this->valeur=valeur;    // accesseur
    defini=true;
}


void SymboleValue::Accept(NoeudVisitor& visitor) {
    if (typeid(visitor) == typeid(AfficherVisitor)) {
        visitor.IncresIndentation();
		visitor.VisitSymboleValue(this);
        visitor.DecresIndentation();
    }
}
